package com.gitee.apiconf.processor;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.gitee.apiconf.common.SpringContext;
import com.gitee.apiconf.entity.GlobalEnum;
import com.gitee.apiconf.entity.LimitAppConfig;
import com.gitee.apiconf.entity.PermApiInfo;
import com.gitee.apiconf.entity.status.ApiInfoStatus;
import com.gitee.apiconf.mapper.PermApiInfoMapper;
import com.gitee.apiconf.service.GlobalConfigService;
import com.gitee.easyopen.bean.Api;
import com.gitee.easyopen.config.ConfigMsg;
import com.gitee.easyopen.limit.LimitStatus;
import com.gitee.fastmybatis.core.query.Query;
import io.netty.channel.Channel;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.math.NumberUtils;

import java.util.ArrayList;
import java.util.List;

public class SyncAppApiProcessor extends AbstractNettyServerProcessor {

    @Override
    public void process(Channel channel, ConfigMsg msg) {
        PermApiInfoMapper apiInfoMapper = SpringContext.getBean(PermApiInfoMapper.class);
        JSONArray arrJson = JSON.parseArray(msg.getData());
        String app = msg.getApp();

        List<PermApiInfo> toBeSave = new ArrayList<>();
        List<LimitAppConfig> tobeSaveLimit = new ArrayList<>();
        List<Long> remainApiIdList = this.listAllApiId(apiInfoMapper, app);
        
        for (int i = 0; i < arrJson.size(); i++) {
            Api api = JSON.parseObject(arrJson.getString(i), Api.class);
            Query query = new Query();
            query.eq("app", app).eq("name", api.getName()).eq("version", api.getVersion());
            PermApiInfo rec = apiInfoMapper.getByQuery(query);
            // 如果数据库没有,保存到数据库
            if(rec == null) {
                rec = new PermApiInfo();
                rec.setApp(msg.getApp());
                rec.setName(api.getName());
                rec.setVersion(api.getVersion());
                rec.setStatus(ApiInfoStatus.USING.getStatus());
                toBeSave.add(rec);
            } else {
            	remainApiIdList.remove(rec.getId());
            }
        }

        // 客户端新增的接口，批量保存
        if(CollectionUtils.isNotEmpty(toBeSave)) {
            apiInfoMapper.saveBatch(toBeSave);
        }

        // 剩下的id表示客户端已经删除,配置中心还存在,标记未使用
        if(CollectionUtils.isNotEmpty(remainApiIdList)) {
            for (Long id : remainApiIdList) {
                PermApiInfo rec = apiInfoMapper.getById(id);
                rec.setStatus(ApiInfoStatus.UN_USED.getStatus());
                apiInfoMapper.update(rec);
            }

        }
    }

    private LimitAppConfig buildLimitAppConfig(PermApiInfo rec) {
        GlobalConfigService globalConfigService = SpringContext.getBean(GlobalConfigService.class);
        LimitAppConfig limitAppConfig = new LimitAppConfig();
        limitAppConfig.setApiId(rec.getId());
        limitAppConfig.setName(rec.getName());
        limitAppConfig.setVersion(rec.getVersion());
        limitAppConfig.setApp(rec.getApp());
        limitAppConfig.setStatus(LimitStatus.CLOSE.getStatus());
        limitAppConfig.setLimitCount(NumberUtils.toInt(globalConfigService.getValue(GlobalEnum.DEFAULT_LIMIT_COUNT),50));
        limitAppConfig.setLimitType(globalConfigService.getValue(GlobalEnum.DEFAULT_LIMIT_TYPE));
        limitAppConfig.setTokenBucketCount(NumberUtils.toInt(globalConfigService.getValue(GlobalEnum.DEFAULT_TOKEN_BUCKET_COUNT),50));
        return limitAppConfig;
    }
    
    private List<Long> listAllApiId(PermApiInfoMapper apiInfoMapper,String app) {
        Query query = new Query();
        query.eq("app", app);
        List<PermApiInfo> allApi = apiInfoMapper.list(query);
        List<Long> ret = new ArrayList<>(allApi.size());
        for (PermApiInfo permApiInfo : allApi) {
            ret.add(permApiInfo.getId());
        }
        return ret;
    }

}
